package com.example;


import com.example.mapper.UserMapper;
import org.apache.ibatis.annotations.Select;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Application {
    /**
     * 拿到参数名和对应的参数值  map.put("id","1") map.put("name","king")
     * @param method
     * @param args
     * @return
     */
    public static Map<String,Object> buildMethodArgNameMap(Method method, Object[] args){
          HashMap<String, Object> nameArgMap=new HashMap<>();
          int[] index={0};
          Parameter[] parameters = method.getParameters();
          Arrays.asList(parameters).forEach(a-> {
              //拿到参数名
              String name=a.getName();
              //将参数名和参数值存起来
              nameArgMap.put(name,args[index[0]++]);
          });
          return nameArgMap;
    }

    //将sql解析
    public static String parseSQL(String sql,Map<String,Object> map){
         StringBuilder stringBuilder=new StringBuilder();
         int length=sql.length();
         for (int i=0;i<length;i++){
             char c=sql.charAt(i);
             if (c=='#'){
                 //拿到#后面这个字符的索引
                 int nextIndex=i+1;
                 //拿到#后面的字符
                 char nextChar=sql.charAt(nextIndex);
                 if (nextChar!='{'){
                     throw new RuntimeException(String.format("这里应该为#{，\n sql:%s\nindex:%d",stringBuilder.toString(),nextChar));
                 }
                 StringBuilder argSB=new StringBuilder();
                 i=parseSQLArg(argSB,sql,nextIndex);
                 String argName=argSB.toString();
                 Object argValue=map.get(argName);
                 stringBuilder.append(argValue.toString());
                 continue;
             }
             stringBuilder.append(c);
         }
         return stringBuilder.toString();
    }

    private static int parseSQLArg(StringBuilder argSB, String sql, int nextIndex) {
           nextIndex++;
           for (;nextIndex<sql.length();nextIndex++){
               char c=sql.charAt(nextIndex);
               if (c!='}'){
                 argSB.append(c);
                 continue;
               }
               if (c=='}'){
                   return nextIndex;
               }
           }
           throw new RuntimeException(String.format("缺少右括号\nindex:%d",nextIndex));
    }

    public static void main(String[] args) {
    UserMapper userMapper= (UserMapper) Proxy.newProxyInstance(Application.class.getClassLoader(), new Class<?>[]{UserMapper.class}, new InvocationHandler() {
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              Select annotation = method.getAnnotation(Select.class);
              //System.out.println(Arrays.toString(args));
              Map<String, Object> map = buildMethodArgNameMap(method, args);
              if (null!=annotation){
                  String[] value=annotation.value();
                  //System.out.println(Arrays.toString(value));
                  String sql=value[0];
                  System.out.println(parseSQL(sql,map));
              }

              return null;
          }
      });
    userMapper.selectUserList(1,"king");
    }
}
